package helper.com.utils;


import cn.hutool.core.util.CharsetUtil;
import cn.hutool.extra.compress.CompressUtil;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.RollingFileAppender;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.Configurator;
import org.springframework.util.Assert;

import java.io.*;
import java.util.*;

/**
 * @author 大忽悠
 * @create 2022/5/17 14:39
 */
public class Log4j2Util {
    /**
     * 日志等级
     */
    private static final Map<String, Level> levelMap = new HashMap<>();
    /**
     * 日志输出目录
     */
    private static  String LOG_DIR="log4j2-logs";

    /**
     * 压缩后的压缩包名称
     */
    private static String ZP_LOG_DIR=LOG_DIR+".zip";

    private static final String ENV_LOG_DIR_KEY="log-dir";

    static {
        levelMap.put("error", Level.ERROR);
        levelMap.put("ERROR", Level.ERROR);
        levelMap.put("warn", Level.WARN);
        levelMap.put("WARN", Level.WARN);
        levelMap.put("info", Level.INFO);
        levelMap.put("INFO", Level.INFO);
        levelMap.put("debug", Level.DEBUG);
        levelMap.put("DEBUG", Level.DEBUG);
        levelMap.put("trace", Level.TRACE);
        levelMap.put("TRACE", Level.TRACE);
    }

     /**
     * 当前传入的日志级别是否合法
     */
    public static Boolean isLegal(String level){
        return levelMap.get(level)!=null;
    }

    /**
     * 改变日志等级,如果loggerName为null或"",表示改变的是rootLogger的日志等级
     */
    public static void changeLevel(String level, String loggerName) throws IOException {
        Level lev = levelMap.get(level);
        Assert.notNull(lev,level+"不是一个合法的日志级别");
        Configurator.setLevel(loggerName==null?"":loggerName,lev);
    }

    /**
     * 改变指定appender日志文件存放目录
     *         LoggerContext context = LoggerContext.getContext(false);
     *         context.updateLoggers();
     *         updateLoggers是动态更新的关键
     * @return
     */
    public static String changeLogFile(String appenderName, String logDir) {
        String oldFileName = check(appenderName, logDir);
        System.setProperty(ENV_LOG_DIR_KEY,logDir);
        Configurator.reconfigure();
        LOG_DIR=logDir;
        return oldFileName;
    }

    /**
     * 设置默认的日志目录
     */
    public static void setDefaultLogDir(){
        System.setProperty(ENV_LOG_DIR_KEY,LOG_DIR);
    }

    private static String check(String appenderName, String logDir) {
        Configuration configuration = LoggerContext.getContext(false).getConfiguration();
        Appender appender = configuration.getAppenders().get(appenderName);
        String err="不存在名字为"+ appenderName +"的RollingFileAppender";
        Assert.notNull(appender,err);
        Assert.isTrue(appender instanceof RollingFileAppender,err);
        String fileName = ((RollingFileAppender) appender).getFileName();
        return fileName;
    }


    /**
     * 返回压缩后的日志压缩包输入流
     */
    public synchronized static File getLogGzFile() throws FileNotFoundException {
        File zpFile = new File(ZP_LOG_DIR);
        CompressUtil.createArchiver(CharsetUtil.CHARSET_UTF_8, ArchiveStreamFactory.ZIP, zpFile)
                .add(new File(LOG_DIR))
                .finish()
                .close();
         return zpFile;
    }

    /**
     * 删除生成的压缩包文件
     */
    public static void delLogGzFile(){
        File file = new File(ZP_LOG_DIR);
        if(file.exists()){
            file.delete();
        }
    }
}
